Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: reimplement password reset #20966

Closed
wants to merge 18 commits into from
Closed

Conversation

raquelmsmith
Copy link
Member

@raquelmsmith raquelmsmith commented Mar 18, 2024

Problem

A few days ago password resets stopped working. Users are sent three reset emails with different tokens, all of which when clicked say the token is invalid or expired.

I added error logging and oddly the errors are never triggered. It's almost like our password reset implementation never gets hit - it's just using the default one.

The email verification flow works in a very similar way to password reset, but instead of being its own endpoint it's an action on the user. This email verification flow still works just fine. As a relatively quick fix I'm going to reimplement the password reset flow in the same way that email verification works to see if that fixes the problem.

Changes

Reimplements password reset flow as actions on the user instead of an independent endpoint.

To do:

  • Frontend changes
  • Remove the old implementation
  • Move all test variants to the new implementation

👉 Stay up-to-date with PostHog coding conventions for a smoother review.

Does this work well for both Cloud and self-hosted?

Should be fine

How did you test this code?

@raquelmsmith raquelmsmith marked this pull request as draft March 18, 2024 03:37
@benjackwhite benjackwhite self-requested a review March 18, 2024 08:12
Copy link
Contributor

github-actions bot commented Mar 18, 2024

Size Change: 0 B

Total Size: 821 kB

ℹ️ View Unchanged
Filename Size
frontend/dist/toolbar.js 821 kB

compressed-size-action

@raquelmsmith raquelmsmith marked this pull request as ready for review March 18, 2024 20:52
@raquelmsmith raquelmsmith requested a review from a team March 18, 2024 20:52
@posthog-bot
Copy link
Contributor

📸 UI snapshots have been updated

2 snapshot changes in total. 0 added, 2 modified, 0 deleted:

  • chromium: 0 added, 2 modified, 0 deleted (diff for shard 2)
  • webkit: 0 added, 0 modified, 0 deleted

Triggered by this commit.

👉 Review this PR's diff of snapshots.

Copy link
Contributor

@benjackwhite benjackwhite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally I approve of this 👍
Just needs to incorporate the fixes from #20993

@@ -67,6 +76,10 @@ class UserEmailVerificationThrottle(UserRateThrottle):
rate = "6/day"


class UserPasswordResetThrottle(UserRateThrottle):
rate = "6/day"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the source of all our issues. This has no "scope" which means all of the throttlers that derive from the base UserRateThrottle will be affecting each others rate limiting.

This attempts to fix that problem #20993

logger = structlog.get_logger(__name__)


class PHPasswordResetTokenGenerator(PasswordResetTokenGenerator):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I think this should be in a sub folder like the services folder to differentiate it from api routers

@@ -413,6 +426,139 @@ def request_email_verification(self, request, **kwargs):

return Response({"success": True})

# Password reset actions

def validate_password_reset_token(self, user_uuid: str, token: str) -> bool:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to indicate this as private

Suggested change
def validate_password_reset_token(self, user_uuid: str, token: str) -> bool:
def _validate_password_reset_token(self, user_uuid: str, token: str) -> bool:

methods=["POST"],
detail=True,
permission_classes=[AllowAny],
throttle_classes=[UserPasswordResetThrottle],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each of these throttle classes arguably should have their own throttle scope
For example what we don't want is that

  1. Request to reset password succeeds but is the second-to-last before being throttled
  2. Email is sent so they click the link
  3. The attempt to verify the password and it succeeds but is the last before being throttled
  4. Now they actually attempt the reset - rate limited!

@raquelmsmith
Copy link
Member Author

Ended up not being needed / was different problem!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants